"use client"
import React, {useState, useRef} from 'react';
import ImageUploader from "@/app/yolo/sign/image-uploader";
import LabelManager from "@/app/yolo/sign/label-manage";
import CanvasManage from './canvas-manage';
import ParseVide from './parse-video'

interface Label {
    startX: number;
    startY: number;
    endX: number;
    endY: number;
    label: string;
    color: string;
    labelIndex: number;
}

const ImageLabelingTool: React.FC = () => {
    const [labels, setLabels] = useState<Label[]>([]);
    const [undoStack, setUndoStack] = useState<Label[][]>([]);
    const [redoStack, setRedoStack] = useState<Label[][]>([]);
    const [currentLabel, setCurrentLabel] = useState('猫');
    const [labelColors, setLabelColors] = useState(new Map<string, string>([['猫', 'red'], ['狗', 'blue']]))
    const [image, setImage] = useState<HTMLImageElement | null>(null);
    const [imageName, setImageName] = useState<string | null>(null);


    // 加载状态
    const [loading, setLoading] = useState('none');

    // 图片列表
    const imageUploaderRef = useRef<{ selectNextImage: () => void }>(null);

    // 查看标签信息
    const handleViewLabels = () => {
        return labels.map((label, index) => (
            <div key={index}>
                标签: {label.label}, 起点: ({label.startX}, {label.startY}), 终点: ({label.endX}, {label.endY})
            </div>
        ));
    };


    // 撤销功能
    const handleUndo = () => {
        if (undoStack.length > 0) {
            const lastState = undoStack[undoStack.length - 1];
            setRedoStack((prevRedoStack) => [...prevRedoStack, labels]);
            setUndoStack((prevUndoStack) => prevUndoStack.slice(0, -1));
            setLabels(lastState);
        }
    };

    // 反撤销功能
    const handleRedo = () => {
        if (redoStack.length > 0) {
            const nextState = redoStack[redoStack.length - 1];
            setUndoStack((prevUndoStack) => [...prevUndoStack, labels].slice(-5));
            setRedoStack((prevRedoStack) => prevRedoStack.slice(0, -1));
            setLabels(nextState);
        }
    };

    // 保存标签和图像到文件夹内
    const saveLabelsToFile = async (imageName: string | null, image: HTMLImageElement | null, labels: Label[]) => {

        if (!imageName || !image) return;

        // 创建一个 canvas 元素用于获取图像数据
        const canvas = document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        const ctx = canvas.getContext('2d');
        if (ctx) {
            ctx.drawImage(image, 0, 0);
        }

        // 将图像转换为 Blob 对象
        const blob = await new Promise<Blob | null>((resolve) => {
            canvas.toBlob((blob) => resolve(blob), 'image/png');
        });

        if (!blob) return;
        setLoading("block")

        // 使用 FormData 传递数据
        const formData = new FormData();
        formData.append('imageName', imageName);
        formData.append('labels', JSON.stringify(labels));
        formData.append('image', blob, `${imageName}.png`);
        formData.append('imageWidth', image.width.toString());
        formData.append('imageHeight', image.height.toString());

        const response = await fetch('/api/file', {
            method: 'POST',
            body: formData,
        });

        if (response.ok) {
            // 这里需要做一个记录, 记录该图片已经打过标签了, 避免重复打标签
            localStorage.setItem(`image_${imageName}`, 'true');
            setLoading("none")
            // 选择下一个图片
            imageUploaderRef.current?.selectNextImage();
        } else {
            setLoading("none")
        }
    };

    // base64 转化为图片
    const handleDataFromChild = (image: { name: string, src: string }) => {
        base64ToImageElement(image.src)
            .then(() => {
                const img = new Image();
                img.onload = () => {
                    setLabels([])
                    setUndoStack([]);
                    setRedoStack([]);
                };
                img.src = image.src
                setImageName(image.name);
                setImage(img);
            })
            .catch((error) => {
                console.error('转化失败', error);
            });
    }

    const base64ToImageElement = (base64: string): Promise<HTMLImageElement> => {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.src = base64;
            img.onload = () => {
                resolve(img); // 图片加载完成，返回 HTMLImageElement
            };
            img.onerror = (error) => {
                reject(error); // 加载失败，返回错误
            };
        });
    };

    // 处理从 LabelManager 接收的新标签
    const handleNewLabel = (name: string, color: string) => {
        setLabelColors((prevColors) => new Map(prevColors).set(name, color));
        setCurrentLabel(name);
    };

    // 处理标签改变
    const onSetLabelsHandler = (label: Label) => {
        setLabels((prevLabels: Label[]) => {
            const newLabels = [
                ...prevLabels,
                label
            ];
            setUndoStack((prevUndoStack) => [...prevUndoStack, prevLabels].slice(-5));
            setRedoStack([]);
            return newLabels;
        });
        return labels;
    }

    return (
        <div className="container mx-auto p-4">
            {/*选择文件夹.批量图片*/}
            <div className="flex space-x-4  mt-1.5">
                <ImageUploader ref={imageUploaderRef} onData={handleDataFromChild}/>
            </div>

            <div className="flex space-x-4 mt-1.5">
                <CanvasManage
                    image={image}
                    currentLabel={currentLabel}
                    labelColors={labelColors}
                    onSetLabels={onSetLabelsHandler}
                    labels={labels}
                ></CanvasManage>
                <div className="flex flex-col space-y-4 mt-1.5">
                    <div className="flex space-x-4">
                        <button
                            onClick={handleUndo}
                            disabled={undoStack.length === 0}
                            className="btn btn-sm">
                            撤销
                        </button>
                        <button
                            onClick={handleRedo}
                            disabled={redoStack.length === 0}
                            className="btn btn-sm">
                            反撤销
                        </button>
                        <button
                            onClick={() => saveLabelsToFile(imageName, image, labels)}
                            className="btn btn-sm ml-auto">
                            保存标签 <span className="loading loading-ring loading-sm"
                                           style={{display: loading}}></span>
                        </button>
                        <LabelManager
                            currentLabel={currentLabel}
                            labelColors={labelColors}
                            onLabelChange={setCurrentLabel}
                            onSaveLabel={handleNewLabel}
                        />
                    </div>
                    <div className="overflow-auto max-h-40">
                        {handleViewLabels()}
                    </div>
                </div>
            </div>
            <ParseVide/>
        </div>
    )
        ;
};

export default ImageLabelingTool;
